﻿using  HalconDotNet;
using Halcon二次开发.Model;
using Halcon二次开发.Model.储存每个Controller的单例对象;
using Halcon二次开发.Model.储放所有单例.储存每个单例界面;
using Halcon二次开发.Model.工具区域的扩展类;
using Halcon二次开发.Model.自定义控件;
using Halcon二次开发.Tools;
using Halcon二次开发.View.图片显示弹窗;
using Halcon二次开发.View.多模板匹配;
using Newtonsoft.Json.Linq;
using Sunny.UI;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Data.Common;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using System.Windows.Forms;
using System.Windows.Shapes;
using System.Xml.Linq;
using static System.Windows.Forms.LinkLabel;
using static System.Windows.Forms.MonthCalendar;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolTip;
using Rectangle = System.Drawing.Rectangle;

namespace Halcon二次开发.Controller.多模板匹配
{
    /// <summary>
    /// 模板匹配
    /// </summary>
    public class Shap_S_Matching
    {
        /// <summary>
        /// 矩形2工具包
        /// </summary>
        GenRectangle2 draw;
        /// <summary>
        /// 矩形2工具包
        /// </summary>
        GenCirle drawCirle;
        /// <summary>
        /// 当前图像对象,输入图像
        /// </summary>
        public HObject HideIntputImage;
        /// <summary>
        /// 模板匹配变量
        /// </summary>
        public HTuple HideOutputShapeModel;
        /// <summary>
        /// 输出变量OutRow,OutColumn,OutAngle是实时位置
        /// OutStandardRow，OutStandardColumn是基准位置，根据模板来决定基准
        /// OutHImage是输出处理好之后的图像
        /// </summary>
        public double HideOutputRow;
        public double HideOutputColumn;
        public double HideOutputPhi;
        public double HideOutputStandardRow;
        public double HideOutputStandardColumn;
        public double HideOutputScoreShape;//当前模板的分数 

        public double[] HideOutputArrayRows; //输出数组X
        public double[] HideOutputArrayColumns; //输出数组Y
        public double[] HideOutputArrayPhis; //输出数组角度
        public double[] HideOutputArrayScales; //输出缩放比例
        public double[] HideOutputArrayScores; //输出分数

        HObject PMA_Contours;  //模板的轮廓

        /// <summary>
        /// 控件句柄
        /// </summary>
        HDrawingObjectEx region = null;
        /// <summary>
        /// 自定义控件界面
        /// </summary>
        Rectangle2Control rectangle;
        CirleControl cirle;

        private H_PMA_S_AlignToolForm pmaForm { get; set; }

        public HwindowFlowNodeUrseControl hwindowFlowNode;

        public Shap_S_Matching(H_PMA_S_AlignToolForm pmaForm, Rectangle2Control rectangle, CirleControl cirle, HwindowFlowNodeUrseControl hwindowFlowNode)
        {
            //获取当前工位
            this.hwindowFlowNode = hwindowFlowNode;
            this.pmaForm = pmaForm;
            //调用工具包-矩形2
            draw = new GenRectangle2();
            drawCirle = new GenCirle();

            this.rectangle = rectangle;
            this.cirle = cirle;
        }
        public Shap_S_Matching()
        {
        }

        /// <summary>
        /// 画圆
        /// </summary>
        /// <param name="hWindon">句柄</param>
        public void DrawCirle()
        {
            //互锁
            draw.ClearObject(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            CirleControl cirle = (CirleControl)pmaForm.groupBox3.Controls[0];
            double x = double.Parse(cirle.XUpDown.Value + "");
            double y = double.Parse(cirle.YUpDown.Value + "");
            double radius = double.Parse(cirle.RaduisUpDown.Value + "");
            drawCirle.DrawCirle(hwindowFlowNode.hSmartWindowControl1.HalconWindow, x, y, radius, cirle.XUpDown, cirle.YUpDown, cirle.RaduisUpDown);
        }
        /// <summary>
        /// 画矩形
        /// </summary>
        /// <param name="hWindon">句柄</param>
        //将矩形的Length存储起来
        private double rectangleHigth = 0;
        private double rectangleLigth = 0;
        public void DrawRectangle2()
        {
            //互锁
            drawCirle.ClearObject(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            Rectangle2Control rectangle2 = (Rectangle2Control)pmaForm.groupBox3.Controls[0];
            double x = double.Parse(rectangle2.XUpDown.Value + "");
            double y = double.Parse(rectangle2.YUpDown.Value + "");
            double phi = double.Parse(rectangle2.PhiUpDown.Value + "");
            double length1 = double.Parse(rectangle2.Length1UpDown.Value + "");
            double length2 = double.Parse(rectangle2.Length2UpDown.Value + "");
            rectangleHigth = length1;
            rectangleLigth = length2;
            draw.DrawRectangle2(hwindowFlowNode.hSmartWindowControl1.HalconWindow, x, y, phi, length1, length2, rectangle2.XUpDown, rectangle2.YUpDown, rectangle2.PhiUpDown, rectangle2.Length1UpDown, rectangle2.Length2UpDown, pmaForm);
        }
        /// <summary>
        /// 保存模板
        /// </summary>
        public void SaveShapeModel(string path)
        {
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            if (HideOutputShapeModel == null)
            {
                return;
            }
            //"Data\\工程文件\\3\\2任务文件\\模板匹配文件\\多目标模型匹配0工位模板.shm
            string[] strs = path.Split(new char[] { '\\' });
            string str = "";
            if (strs.Length>0)
            {
                for (int i = 0; i < strs.Length - 1; i++)
                {
                    str += strs[i];
                    if (i != strs.Length - 2)
                    {
                        str += "\\";
                    }
                }
            }
            if (!Directory.Exists(str)) {
                Directory.CreateDirectory(str); 
            }
            try
            {
                HOperatorSet.WriteShapeModel(HideOutputShapeModel, path);
            }
            catch { 
                throw new Exception("保存的模板文件路径错误!\r\n");
            }
            
        }
        /// <summary>
        /// 创建模板
        /// </summary>
        /// <param name="hWindon">句柄</param>
        //paper是用来决定是创建模板时建立模板的
        private static bool paper = false;
        public void CreatShapeModel()
        {
            HOperatorSet.ClearWindow(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            HOperatorSet.DispObj(HideIntputImage, hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            HObject ROI_0 = null;
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            //使用涂抹区域
            if (dragRegion != null)
            {
                HOperatorSet.GenRectangle2(out HObject rectangle, double.Parse(draw.XUpdown.Value + "")
                    , double.Parse(draw.YUpdown.Value + ""), double.Parse(draw.PhiUpdown.Value + "")
                    , double.Parse(draw.Length1Updown.Value + ""), double.Parse(draw.Length2Updown.Value + ""));
                paper = true;
                try
                {
                    //区域相减
                    HOperatorSet.Difference(rectangle, dragRegion, out HObject regionDifference);
                    ROI_0 = regionDifference;
                    HOperatorSet.ReduceDomain(HideIntputImage, regionDifference, out HObject imageReduced);

                    HOperatorSet.CreateScaledShapeModel(imageReduced, "auto", (new HTuple(-360).TupleRad())
                    , (new HTuple(360).TupleRad()), "auto", 0.9, 1.1, "auto", "auto", "use_polarity",
                    "auto", "auto", out HideOutputShapeModel);

                }
                catch (HOperatorException e)
                {
                    if (e.GetErrorCode() == 3111)
                    {
                        DrawRectangle2();
                        CreatShapeModel();
                    }
                }
            }
            else
            {
                //获取位置信息,谁有值就执行谁
                draw.GetPoint(out HDrawingObjectEx region1);
                drawCirle.GetPoint(out HDrawingObjectEx region2);
                if (region1 != null)
                {
                    //矩形
                    region = region1;
                    HOperatorSet.GenRectangle2(out ROI_0, region.hTuples[0], region.hTuples[1], region.hTuples[2], region.hTuples[3], region.hTuples[4]);
                    draw.ClearObject(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
                }
                else if (region2 != null)
                {
                    //圆形
                    region = region2;
                    HOperatorSet.GenCircle(out ROI_0, region.hTuples[0], region.hTuples[1], region.hTuples[2]);
                    drawCirle.ClearObject(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
                }

                paper = true;
                if (ROI_0 == null) return;
                HOperatorSet.ReduceDomain(HideIntputImage, ROI_0, out HObject imageReduced);

                try
                {
                    HOperatorSet.CreateScaledShapeModel(imageReduced, "auto", (new HTuple(-360).TupleRad())
                    , (new HTuple(360).TupleRad()), "auto", 0.9, 1.1, "auto", "auto", "use_polarity",
                    "auto", "auto", out HideOutputShapeModel);
                }
                catch (HOperatorException e)
                {
                    if (e.GetErrorCode() == 3111)
                    {
                        DrawRectangle2();
                        CreatShapeModel();
                    }
                }
            }
            //释放涂抹区域
            dragRegion = null;
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "green");
            HOperatorSet.GetShapeModelContours(out HObject ho_ModelContours, HideOutputShapeModel, 1);
            HOperatorSet.AreaCenter(ROI_0, out HTuple hv_Area, out HTuple hv_Row1, out HTuple hv_Column1);
            //几何变换的实现
            HOperatorSet.HomMat2dIdentity(out HTuple hv_HomMat2DIdentity);
            HOperatorSet.HomMat2dTranslate(hv_HomMat2DIdentity, hv_Row1, hv_Column1, out HTuple hv_HomMat2DTranslate);
            HOperatorSet.HomMat2dRotate(hv_HomMat2DTranslate, 0, hv_Row1, hv_Column1, out HTuple hv_HomMat2DRotate);
            HOperatorSet.HomMat2dScale(hv_HomMat2DRotate, 1, 1, hv_Row1, hv_Column1, out HTuple hv_HomMat2DScale);
            HOperatorSet.AffineTransContourXld(ho_ModelContours, out PMA_Contours, hv_HomMat2DScale);

            HOperatorSet.DispObj(PMA_Contours, hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            //创建一个供存储基准数据的文件夹
            Directory.CreateDirectory(pmaForm.standardPath);
        }
        /// <summary>
        /// 寻找模版CreatShape
        /// </summary>
        /// <param name="path">模板路径</param>
        /// <param name="hWindon">句柄</param>
        /// /// <param name="value1">模板匹配的分数下限</param>
        /// /// <param name="value2">模板匹配的分数上限</param>
        public void Run()
        {
            HTuple leftTopRow=0, leftTopColumn=0;
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            HObject imageReduced = HideIntputImage;
            //清除模型
            ClearTwoObject(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            //清除字典存储集合
            //HideOutputResults.Clear();
            pmaForm.dataGridView1.Rows.Clear();
            pmaForm.textBox4.Text = "";
            try
            {
                //这里要添加一个搜索区域，去减少模板匹配的搜索时间
                if (pmaForm.comboBox7.Text.Equals("开启"))
                {
                    try
                    {
                        if (searchArea != null)
                        {
                            searchArea.Dispose();
                            searchArea.ClearDrawingObject();
                        }
                        HOperatorSet.SetDraw(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "margin");
                        //生成一个矩形区域

                        HOperatorSet.GenRectangle2(out HObject rectanglephi, double.Parse(pmaForm.numericUpDown21.Value + ""), double.Parse(pmaForm.numericUpDown22.Value + ""), double.Parse(pmaForm.numericUpDown23.Value + ""), double.Parse(pmaForm.numericUpDown24.Value + ""), double.Parse(pmaForm.numericUpDown25.Value + ""));

                        //这里要获得一下左上角角点,硬触发也得要使用,左上角
                        //Get_Rectangle2Infor(rectanglephi, out leftTopRow, out leftTopColumn);

                        //显示框是否显示
                        if (pmaForm.comboBox2.Text=="开启")
                        {
                            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, pmaForm.BorderColor);
                            HOperatorSet.DispObj(rectanglephi, hwindowFlowNode.hSmartWindowControl1.HalconWindow);
                            //410 542
                            //HOperatorSet.SetFont(hwindowFlowNode.hSmartWindowControl1.HalconWindow, $"微软雅黑-Normal-{int.Parse(pmaForm.fontSize.Value + "")}");
                            //HOperatorSet.DispText(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "搜索框", "image", leftTopRow - 57.000 + double.Parse(pmaForm.Office_Y.Value + ""), leftTopColumn - 50.000 + double.Parse(pmaForm.Office_X.Value + ""), pmaForm.FontColor, "box", 0);
                        }

                        HOperatorSet.ReduceDomain(HideIntputImage, rectanglephi, out imageReduced);

                        HOperatorSet.CropDomain(imageReduced,out imageReduced);

                    }
                    catch (Exception ex)
                    {
                        (FormDb.Db["Form1"] as Form1).textBox1.AppendText("设置模板匹配搜索区域失败" + ":" + ex.Message + "\r\n");
                    }
                }

                HOperatorSet.ReadShapeModel(pmaForm.filePath, out HTuple hv_ModelID2);
                HOperatorSet.GetShapeModelContours(out HObject ho_ModeContours, hv_ModelID2, 1);
                if (hv_ModelID2 == null)
                {
                    throw new Exception("寻找模板失败");
                }
                
                //金字塔层数越高处理速度越快 NumLevels
                //搜索启发式的（0：安全 但速度很慢;1：快速但可能会错过匹配项） Greediness
                HOperatorSet.FindScaledShapeModels(imageReduced, hv_ModelID2, (new HTuple(int.Parse(pmaForm.numericUpDown4.Value.ToString()))).TupleRad(), (new HTuple(int.Parse(pmaForm.numericUpDown3.Value.ToString()))).TupleRad(),
                    1, 1, double.Parse(pmaForm.numericUpDown1.Value.ToString()), int.Parse(pmaForm.numericUpDown13.Value.ToString()), double.Parse(pmaForm.numericUpDown7.Value.ToString()), pmaForm.PMA_SubPixel, int.Parse(pmaForm.numericUpDown5.Value.ToString()), double.Parse(pmaForm.numericUpDown6.Value.ToString()),
                    out HTuple hv_RowShape, out HTuple hv_ColumnShape, out HTuple hv_AngleShape, out HTuple hv_ScaleShape, out HTuple hv_ScoreShape, out HTuple hv_Model);

                //这里要加上一个偏移,让裁剪的图片回归到原始图像坐标
                for (int i = 0; i < hv_RowShape.Length; i++) {
                    hv_RowShape[i] = hv_RowShape[i] + leftTopRow;
                    hv_ColumnShape[i] = hv_ColumnShape[i] + leftTopColumn;
                }
                

                //记录一下方便后续调用
                if (paper)
                {
                    //点击记录基准数据
                    HideOutputStandardRow = hv_RowShape[0];
                    HideOutputStandardColumn = hv_ColumnShape[0];
                    //将这个基准数据进行保存下来
                    List<double> doubleList = new List<double>();
                    doubleList.Add(HideOutputStandardRow);
                    doubleList.Add(HideOutputStandardColumn);
                    //将这个数据进行持久化
                    HelpJsons.Write<double>(doubleList, pmaForm.standardPath + "\\" + "standar.txt");
                    paper = false;
                }
                //添加给输出  x，y位置，角度
                try
                {
                    //模板匹配失败,将值汇纳为0
                    if (hv_RowShape.Length == 0)
                    {
                        HideOutputRow = 0;
                        HideOutputColumn = 0;
                        HideOutputPhi = 0;

                        HideOutputArrayRows = null;
                        HideOutputArrayColumns = null;
                        HideOutputArrayPhis = null;
                        HideOutputArrayScales = null;
                        HideOutputArrayScores = null;
                        throw new Exception();
                    }
                    HideOutputRow = hv_RowShape[0];
                    HideOutputColumn = hv_ColumnShape[0];
                    HideOutputPhi = hv_AngleShape[0];

                    HideOutputArrayRows = hv_RowShape;
                    HideOutputArrayColumns = hv_ColumnShape;
                    HideOutputArrayPhis = hv_AngleShape;
                    HideOutputArrayScales = hv_ScaleShape;
                    HideOutputArrayScores = hv_ScoreShape;
                }
                catch
                {
                    throw new Exception("寻找模板失败");
                }
                //判断是否在分数内
                if (hv_ScoreShape > (double)pmaForm.numericUpDown1.Value)
                {
                    
                    HOperatorSet.TupleLength(hv_RowShape, out HTuple count);
                    for (int i = 0; i < hv_RowShape.Length; i++)
                    {
                        if (pmaForm.comboBox3.SelectedIndex == 0)
                        {
                            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "green");

                            HOperatorSet.DispCross(hwindowFlowNode.hSmartWindowControl1.HalconWindow, hv_RowShape[i], hv_ColumnShape[i], 10, 90);

                            HOperatorSet.HomMat2dIdentity(out HTuple hv_HomMat2DIdentity);
                            HOperatorSet.HomMat2dTranslate(hv_HomMat2DIdentity, hv_RowShape[i], hv_ColumnShape[i], out HTuple hv_HomMat2DTranslate);
                            HOperatorSet.HomMat2dRotate(hv_HomMat2DTranslate, hv_AngleShape[i], hv_RowShape[i], hv_ColumnShape[i],
                                out HTuple hv_HomMat2DRotate);
                            HOperatorSet.HomMat2dScale(hv_HomMat2DRotate, hv_ScaleShape[i], hv_ScaleShape[i], hv_RowShape[i], hv_ColumnShape[i],
                                out HTuple hv_HomMat2DScale);

                            HOperatorSet.AffineTransContourXld(ho_ModeContours, out HObject ho_AffineTransContour, hv_HomMat2DScale);
                            HOperatorSet.DispObj(ho_AffineTransContour, hwindowFlowNode.hSmartWindowControl1.HalconWindow);
                        }
                        //sort_region
                        pmaForm.dataGridView1.Rows.Add(i, hv_RowShape[i].D, hv_ColumnShape[i].D, hv_AngleShape[i].D, hv_ScaleShape[i].D, hv_ScoreShape[i].D);
                    }
                }
                else
                {
                    pmaForm.textBox4.Text = "丢失分数为: " + hv_ScoreShape;
                    throw new Exception("匹配失败");
                }
                //将我们的模板匹配的分数给到输出接口
                HideOutputScoreShape = hv_ScoreShape;


            }
            catch (Exception ex)
            {
                string str = string.Empty;
                if (ex.Message.Contains("匹配失败!"))
                {
                    str = "匹配失败!";
                }
                else if (ex.Message.Contains("寻找模板失败!"))
                {
                    str = "寻找模板失败!";
                }
                else if (ex.Message.Contains("样品不合格,间距匹配失败"))
                {
                    str = "样品不合格,间距匹配失败";
                }
                else
                {
                    str = "模板匹配运行失败，请检查你的模板是否正确!";
                }
                throw new Exception(str);
            }
        }

        public void Get_Rectangle2Infor(HObject region,out HTuple LeftRow,out HTuple LeftColumn) {
            HOperatorSet.GetRegionContour(region,out HTuple rows,out HTuple columns);
            LeftRow = rows.TupleMin();
            LeftColumn = columns.TupleMin();
        }
        public static void Get_Rectangle2Infor(HObject region, out HTuple LeftRow, out HTuple LeftColumn,bool paper)
        {
            HOperatorSet.GetRegionContour(region, out HTuple rows, out HTuple columns);
            LeftRow = rows.TupleMin();
            LeftColumn = columns.TupleMin();
        }
        /// <summary>
        /// 计量模型移动方法
        /// </summary>
        public void Move(Object sender)
        {
            //System.Windows.Forms.NumericUpDown number = (sender as System.Windows.Forms.NumericUpDown);
            //UserControl control = (UserControl)number.Parent;
            //if (control.Name == "Rectangle2Control")
            //{
            //    Rectangle2Control rectangle = (Rectangle2Control)number.Parent;
            //    if (rectangle != null)
            //    {
            //        draw.Move(hwindowFlowNode.hSmartWindowControl1.HalconWindow, double.Parse(rectangle.XUpDown.Value + ""), double.Parse(rectangle.YUpDown.Value + ""), double.Parse(rectangle.PhiUpDown.Value + ""), double.Parse(rectangle.Length1UpDown.Value + "")
            //            , double.Parse(rectangle.Length2UpDown.Value + ""), pmaForm.textBox3.Text);
            //    }
            //}
            //else if (control.Name == "CirleControl")
            //{
            //    CirleControl cirle = (CirleControl)number.Parent;
            //    if (control != null)
            //    {
            //        drawCirle.Move(hwindowFlowNode.hSmartWindowControl1.HalconWindow, double.Parse(cirle.XUpDown.Value + ""), double.Parse(cirle.YUpDown.Value + ""), double.Parse(cirle.RaduisUpDown.Value + ""), pmaForm.textBox3.Text);
            //    }
            //}
        }
        public void ClearTwoObject(HWindow hWindon)
        {
            //清除模型
            if (draw != null)
            {
                draw.ClearObject(hWindon);
            }

            if (drawCirle != null)
            {
                drawCirle.ClearObject(hWindon);
            }
        }
        /// <summary>
        /// 工具的单次运行
        /// </summary>
        public void Tool_Run()
        {
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.ClearWindow();
            HOperatorSet.DispObj(HideIntputImage, hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            Run();
        }
        /// <summary>
        /// 搜索区域
        /// </summary>
        public HDrawingObject searchArea;
        public void DrawSearch()
        {
            if (HideIntputImage == null) return;
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.ClearWindow();
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(HideIntputImage);
            searchArea = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.RECTANGLE2, new HTuple[] { 50, 100, 0, 50, 50 });
            searchArea.SetDrawingObjectParams("color", "green");
            //线段拖动触发事件注册
            searchArea.OnDrag(RectangleDrawResize);
            //线段长度修改触发事件注册
            searchArea.OnResize(RectangleVerifyResize);
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.AttachDrawingObjectToWindow(searchArea);
        }
        /// <summary>
        /// 放置搜索区域
        /// </summary>
        public void Put_Search() {
            searchArea.ClearDrawingObject();
            if (HideIntputImage == null) return;
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.ClearWindow();
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(HideIntputImage);
            if (searchArea == null) return;


            //410 542
            HOperatorSet.SetDraw(hwindowFlowNode.hSmartWindowControl1.HalconWindow,"margin");
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, pmaForm.BorderColor);
            HOperatorSet.GenRectangle2(out HObject rectangle, double.Parse(pmaForm.numericUpDown21.Value + ""), double.Parse(pmaForm.numericUpDown22.Value + ""), double.Parse(pmaForm.numericUpDown23.Value + ""), double.Parse(pmaForm.numericUpDown24.Value + ""), double.Parse(pmaForm.numericUpDown25.Value + ""));

            Get_Rectangle2Infor(rectangle, out HTuple leftTopRow, out HTuple leftTopColumn);

            HOperatorSet.SetFont(hwindowFlowNode.hSmartWindowControl1.HalconWindow, $"微软雅黑-Normal-{int.Parse(pmaForm.fontSize.Value + "")}");
            HOperatorSet.DispText(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "搜索框", "image", leftTopRow - 57.000 + double.Parse(pmaForm.Office_Y.Value + ""), leftTopColumn - 50.000 + double.Parse(pmaForm.Office_X.Value + ""), pmaForm.FontColor, "box", 0);
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(rectangle);
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "red");
            HOperatorSet.SetDraw(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "fill");
        }
        /// <summary>
        /// 移动搜索框
        /// </summary>
        public void Move_Search(){
            if (HideIntputImage == null) return;

            hwindowFlowNode.hSmartWindowControl1.HalconWindow.ClearWindow();
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(HideIntputImage);

            
            //410 542
            HOperatorSet.SetDraw(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "margin");
            HOperatorSet.GenRectangle2(out HObject rectangle, double.Parse(pmaForm.numericUpDown21.Value + ""), double.Parse(pmaForm.numericUpDown22.Value + ""), double.Parse(pmaForm.numericUpDown23.Value + ""), double.Parse(pmaForm.numericUpDown24.Value + ""), double.Parse(pmaForm.numericUpDown25.Value + ""));

            Get_Rectangle2Infor(rectangle, out HTuple leftTopRow, out HTuple leftTopColumn);
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, pmaForm.BorderColor);
            HOperatorSet.SetFont(hwindowFlowNode.hSmartWindowControl1.HalconWindow, $"微软雅黑-Normal-{int.Parse(pmaForm.fontSize.Value+"")}");  
            HOperatorSet.DispText(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "搜索框", "image", leftTopRow -57.000+ double.Parse(pmaForm.Office_Y.Value + ""), leftTopColumn - 50.000 + double.Parse(pmaForm.Office_X.Value + ""), pmaForm.FontColor, "box", 0);
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(rectangle);
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "red");
            HOperatorSet.SetDraw(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "fill");
        }
        /// <summary>
        /// 关闭搜索框
        /// </summary>
        public void Colse_Search() {
            try
            {
                hwindowFlowNode.hSmartWindowControl1.HalconWindow.ClearWindow();
                hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(HideIntputImage);
                Run();
            }
            catch { }
        }
        /// <summary>
        /// 打开搜索框
        /// </summary>
        public void Open_Search() {
            double Row = double.Parse(pmaForm.numericUpDown21.Value + "");
            double Column = double.Parse(pmaForm.numericUpDown22.Value + "");

            if (Row==0&&Column==0)
            {
                return;
            }
            //410 542
            HOperatorSet.SetDraw(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "margin");
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, pmaForm.BorderColor);
            HOperatorSet.GenRectangle2(out HObject rectangle, double.Parse(pmaForm.numericUpDown21.Value + ""), double.Parse(pmaForm.numericUpDown22.Value + ""), double.Parse(pmaForm.numericUpDown23.Value + ""), double.Parse(pmaForm.numericUpDown24.Value + ""), double.Parse(pmaForm.numericUpDown25.Value + ""));

            Get_Rectangle2Infor(rectangle, out HTuple leftTopRow, out HTuple leftTopColumn);

            HOperatorSet.SetFont(hwindowFlowNode.hSmartWindowControl1.HalconWindow, $"微软雅黑-Normal-{int.Parse(pmaForm.fontSize.Value + "")}");
            HOperatorSet.DispText(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "搜索框", "image", leftTopRow + double.Parse(pmaForm.Office_Y.Value + ""), leftTopColumn + double.Parse(pmaForm.Office_X.Value + ""), pmaForm.FontColor, "box", 0);
            hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(rectangle);
            HOperatorSet.SetDraw(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "fill");
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "red");
        }

        private void RectangleDrawResize(HDrawingObject drawid, HWindow window, string type)
        {
            RectangleDrawSearch(drawid);
        }
        private void RectangleVerifyResize(HDrawingObject drawid, HWindow window, string type)
        {
            RectangleDrawSearch(drawid);
        }
        /// <summary>
        /// 矩形拖动或者修改时触发该事件
        /// </summary>
        /// <param name="drawid"></param>
        private void RectangleDrawSearch(HDrawingObject drawid)
        {
            try
            {
                (FormDb.Db["Form1"] as Form1).Cursor = Cursors.Cross;
                //创建一个要得到对象属性的元组
                var attTuple = new HTuple("row", "column", "phi", "length1", "length2");
                //获取对应的属性
                var valueTuple = drawid.GetDrawingObjectParams(attTuple);
                //将矩形的坐标给到控件
                pmaForm.numericUpDown21.Value = (decimal)valueTuple[0].D;
                pmaForm.numericUpDown22.Value = (decimal)valueTuple[1].D;
                pmaForm.numericUpDown23.Value = (decimal)valueTuple[2].D;
                pmaForm.numericUpDown24.Value = (decimal)valueTuple[3].D;
                pmaForm.numericUpDown25.Value = (decimal)valueTuple[4].D;
            }
            catch { }
        }
        /// <summary>
        /// 硬触发模板匹配
        /// </summary>
        public static void HardRun(HObject HideIntputImage,string filePath,H_PMA_S_AlignToolForm pmaForm, HDrawingObject searchArea, HSmartWindowControl hSmartWindowControl,ref double[] HideOutputArrayRows,ref double[] HideOutputArrayColumns,ref double[] HideOutputArrayPhis,ref double[] HideOutputArrayScores)
        {
            HTuple leftTopRow = 0, leftTopColumn = 0;
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            HObject imageReduced = HideIntputImage;
            try
            {
                //这里要添加一个搜索区域，去减少模板匹配的搜索时间
                if (pmaForm.comboBox7.Text.Equals("开启"))
                {
                    HObject rectanglephi = new HObject();
                    try
                    {
                        HOperatorSet.GenRectangle2(out rectanglephi, double.Parse(pmaForm.numericUpDown21.Value + ""), double.Parse(pmaForm.numericUpDown22.Value + ""), double.Parse(pmaForm.numericUpDown23.Value + ""), double.Parse(pmaForm.numericUpDown24.Value + ""), double.Parse(pmaForm.numericUpDown25.Value + ""));

                        //这里要获得一下左上角角点,硬触发也得要使用
                        //Get_Rectangle2Infor(rectanglephi, out leftTopRow, out leftTopColumn, true);
                        //显示框是否显示
                        if (pmaForm.comboBox2.Text == "开启")
                        {
                            HOperatorSet.SetColor(hSmartWindowControl.HalconWindow, pmaForm.BorderColor);
                            HOperatorSet.DispObj(rectanglephi, hSmartWindowControl.HalconWindow);
                            //410 542
                            //HOperatorSet.SetFont(hSmartWindowControl.HalconWindow, $"微软雅黑-Normal-{int.Parse(pmaForm.fontSize.Value + "")}");
                            //HOperatorSet.DispText(hSmartWindowControl.HalconWindow, "搜索框", "image", leftTopRow - 57.000 + double.Parse(pmaForm.Office_Y.Value + ""), leftTopColumn - 50.000 + double.Parse(pmaForm.Office_X.Value + ""), pmaForm.FontColor, "box", 0);
                        }

                        HOperatorSet.ReduceDomain(HideIntputImage, rectanglephi, out imageReduced);

                        HOperatorSet.CropDomain(imageReduced, out imageReduced);

                    }
                    catch (Exception ex)
                    {
                        (FormDb.Db["Form1"] as Form1).textBox1.AppendText("设置模板匹配搜索区域失败" + ":" + ex.Message + "\r\n");
                    }
                    finally
                    {
                        rectanglephi.Dispose();
                    }
                }

                HOperatorSet.ReadShapeModel(pmaForm.filePath, out HTuple hv_ModelID2);
                HOperatorSet.GetShapeModelContours(out HObject ho_ModeContours, hv_ModelID2, 1);
                if (hv_ModelID2 == null)
                {
                    throw new Exception("寻找模板失败");
                }

                //金字塔层数越高处理速度越快 NumLevels
                //搜索启发式的（0：安全 但速度很慢;1：快速但可能会错过匹配项） Greediness
                HOperatorSet.FindScaledShapeModels(imageReduced, hv_ModelID2, (new HTuple(int.Parse(pmaForm.numericUpDown4.Value.ToString()))).TupleRad(), (new HTuple(int.Parse(pmaForm.numericUpDown3.Value.ToString()))).TupleRad(),
                    1, 1, double.Parse(pmaForm.numericUpDown1.Value.ToString()), int.Parse(pmaForm.numericUpDown13.Value.ToString()), double.Parse(pmaForm.numericUpDown7.Value.ToString()), pmaForm.PMA_SubPixel, int.Parse(pmaForm.numericUpDown5.Value.ToString()), 1,
                    out HTuple hv_RowShape, out HTuple hv_ColumnShape, out HTuple hv_AngleShape, out HTuple hv_ScaleShape, out HTuple hv_ScoreShape, out HTuple hv_Model);
                // double.Parse(pmaForm.numericUpDown6.Value.ToString()) 启发式

                //这里要加上一个偏移,让裁剪的图片回归到原始图像坐标
                for (int i = 0; i < hv_RowShape.Length; i++)
                {
                    hv_RowShape[i] = hv_RowShape[i] + leftTopRow;
                    hv_ColumnShape[i] = hv_ColumnShape[i] + leftTopColumn;
                }
                //添加给输出  x，y位置，角度
                try
                {
                    //模板匹配失败,将值汇纳为0
                    if (hv_RowShape.Length == 0)
                    {
                        HideOutputArrayRows = null;
                        HideOutputArrayColumns = null;
                        HideOutputArrayPhis = null;
                        HideOutputArrayScores = null;
                        throw new Exception();
                    }
                    HideOutputArrayRows = hv_RowShape;
                    HideOutputArrayColumns = hv_ColumnShape;
                    HideOutputArrayPhis = hv_AngleShape;
                    HideOutputArrayScores = hv_ScoreShape;
                }
                catch
                {
                    throw new Exception("寻找模板失败");
                }
                //判断是否在分数内
                if (hv_ScoreShape > (double)pmaForm.numericUpDown1.Value)
                {

                    HOperatorSet.TupleLength(hv_RowShape, out HTuple count);
                    for (int i = 0; i < hv_RowShape.Length; i++)
                    {
                        if (pmaForm.comboBox3.SelectedIndex == 0)
                        {
                            HOperatorSet.SetColor(hSmartWindowControl.HalconWindow, "green");

                            HOperatorSet.DispCross(hSmartWindowControl.HalconWindow, hv_RowShape[i], hv_ColumnShape[i], 10, 90);
                        }
                    }
                }
                else
                {
                    throw new Exception("匹配失败");
                }

            }
            catch (Exception ex)
            {
                string str = string.Empty;
                if (ex.Message.Contains("匹配失败!"))
                {
                    str = "匹配失败!";
                }
                else if (ex.Message.Contains("寻找模板失败!"))
                {
                    str = "寻找模板失败!";
                }
                else if (ex.Message.Contains("样品不合格,间距匹配失败"))
                {
                    str = "样品不合格,间距匹配失败";
                }
                else
                {
                    str = "模板匹配运行失败，请检查你的模板是否正确!";
                }
                throw new Exception(str);
            }
            finally
            {

            }
        }
        /// <summary>
        /// 硬触发_模板匹配 
        /// </summary>
        /// <param name="HideIntputImage"></param>
        /// <param name="pmaForm"></param>
        /// <param name="HideOutputArrayRows"></param>
        /// <param name="HideOutputArrayColumns"></param>
        /// <param name="HideOutputArrayPhis"></param>
        /// <param name="HideOutputArrayScores"></param>
        /// <exception cref="Exception"></exception>
        public static void HardRunMatching(HObject HideIntputImage, H_PMA_S_AlignToolForm pmaForm,ref  double[] HideOutputArrayRows,ref   double[] HideOutputArrayColumns,ref  double[] HideOutputArrayPhis,ref  double[] HideOutputArrayScores, HWindowContentManager drawData)
        {
            HTuple leftTopRow = 0, leftTopColumn = 0;
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            HObject imageReduced = HideIntputImage;
            try
            {
                //这里要添加一个搜索区域，去减少模板匹配的搜索时间
                if (pmaForm.comboBox7.Text.Equals("开启"))
                {
                    HObject rectanglephi = new HObject();
                    try
                    {
                        HOperatorSet.GenRectangle2(out rectanglephi, double.Parse(pmaForm.numericUpDown21.Value + ""), double.Parse(pmaForm.numericUpDown22.Value + ""), double.Parse(pmaForm.numericUpDown23.Value + ""), double.Parse(pmaForm.numericUpDown24.Value + ""), double.Parse(pmaForm.numericUpDown25.Value + ""));

                        //这里要获得一下左上角角点,硬触发也得要使用
                        //Get_Rectangle2Infor(rectanglephi, out leftTopRow, out leftTopColumn, true);
                        //显示框是否显示
                        if (pmaForm.comboBox2.Text == "开启")
                        {
                            HTuple hTuple = new HTuple(leftTopRow - 57.000 + (double)pmaForm.Office_Y.Value, leftTopColumn - 50.000 + (double)pmaForm.Office_X.Value);

                            drawData.AddRegion(rectanglephi, "blue");
                            //drawData.AddText("搜索框", hTuple, "black",(int)pmaForm.fontSize.Value);

                        }

                        HOperatorSet.ReduceDomain(HideIntputImage, rectanglephi, out imageReduced);

                        HOperatorSet.CropDomain(imageReduced, out imageReduced);

                    }
                    catch (Exception ex)
                    {
                        (FormDb.Db["Form1"] as Form1).textBox1.AppendText("设置模板匹配搜索区域失败" + ":" + ex.Message + "\r\n");
                    }
                    finally
                    {
                        rectanglephi.Dispose();
                    }
                }
                if ( pmaForm.controller.HideOutputShapeModel == null||pmaForm.controller.HideOutputShapeModel.Length == 0)
                {
                    
                    HOperatorSet.ReadShapeModel(pmaForm.filePath, out HTuple  hv_ModelID2);
                    Interlocked.Exchange(ref pmaForm.controller.HideOutputShapeModel, hv_ModelID2);
                };
                if (pmaForm.controller.HideOutputShapeModel == null|| pmaForm.controller.HideOutputShapeModel.Length == 0)
                {
                    throw new Exception("寻找模板失败");
                }
                HTuple angleStart = new HTuple((double)pmaForm.numericUpDown4.Value).TupleRad();
                HTuple angleExtent = new HTuple((double)pmaForm.numericUpDown3.Value).TupleRad();
               
                HTuple hv_RowShape, hv_ColumnShape, hv_AngleShape, hv_ScaleShape, hv_ScoreShape, hv_Model;
                //金字塔层数越高处理速度越快 NumLevels
                //搜索启发式的（0：安全 但速度很慢;1：快速但可能会错过匹配项） Greediness
                HOperatorSet.FindScaledShapeModels(imageReduced, pmaForm.controller.HideOutputShapeModel, angleStart, angleExtent,1, 1, (double)pmaForm.numericUpDown1.Value, (int)pmaForm.numericUpDown13.Value, (double)pmaForm.numericUpDown7.Value, pmaForm.PMA_SubPixel, (int)pmaForm.numericUpDown5.Value, 1,
                    out  hv_RowShape, out  hv_ColumnShape, out  hv_AngleShape, out  hv_ScaleShape, out  hv_ScoreShape, out  hv_Model);
                // double.Parse(pmaForm.numericUpDown6.Value.ToString()) 启发式

                //这里要加上一个偏移,让裁剪的图片回归到原始图像坐标
                for (int i = 0; i < hv_RowShape.Length; i++)
                {
                    hv_RowShape[i] = hv_RowShape[i] + leftTopRow;
                    hv_ColumnShape[i] = hv_ColumnShape[i] + leftTopColumn;
                }
                //添加给输出  x，y位置，角度
                try
                {
                    //模板匹配失败,将值汇纳为0
                    if (hv_RowShape.Length == 0)
                    {
                        //HideOutputArrayRows = null;
                        //HideOutputArrayColumns = null;
                        //HideOutputArrayPhis = null;
                        //HideOutputArrayScores = null;
                        throw new Exception("寻找模板失败");
                    }else
                    {
                        HideOutputArrayRows=new double[hv_RowShape.Length];
                        HideOutputArrayColumns= new double[hv_RowShape.Length];
                        HideOutputArrayPhis = new double[hv_RowShape.Length];
                        HideOutputArrayScores = new double[hv_RowShape.Length];
                    }
                    for (int i = 0; i < hv_ColumnShape.Length;i++)
                    {
                        HideOutputArrayRows[i] = hv_RowShape[i];
                        HideOutputArrayColumns[i] = hv_ColumnShape[i];
                        HideOutputArrayPhis[i] = hv_AngleShape[i];
                        HideOutputArrayScores[i] = hv_ScoreShape[i];
                    }
                }
                catch
                {
                    throw new Exception("寻找模板失败");
                }
                finally
                {
                    angleStart?.Dispose();
                    angleExtent?.Dispose();
                }                //判断是否在分数内
                if (hv_ScoreShape > (double)pmaForm.numericUpDown1.Value)
                {

                    HOperatorSet.TupleLength(hv_RowShape, out HTuple count);
                    for (int i = 0; i < hv_RowShape.Length; i++)
                    {
                        if (pmaForm.comboBox3.SelectedIndex == 0)
                        {
                            HTuple possion = new HTuple(hv_RowShape[i].D, hv_ColumnShape[i].D);
                            drawData.AddCross(possion,10,"green");
                        }
                    }
                }
                else
                {
                    throw new Exception("匹配失败");
                }
                hv_RowShape?.Dispose();
                hv_ColumnShape?.Dispose();
                hv_AngleShape?.Dispose();
                hv_ScaleShape?.Dispose();
                hv_ScoreShape?.Dispose();
                hv_Model?.Dispose();

            }
            catch (Exception ex)
            {
                string str = string.Empty;
                if (ex.Message.Contains("匹配失败!"))
                {
                    str = "匹配失败!";
                }
                else if (ex.Message.Contains("寻找模板失败!"))
                {
                    str = "寻找模板失败!";
                }
                else if (ex.Message.Contains("样品不合格,间距匹配失败"))
                {
                    str = "样品不合格,间距匹配失败";
                }
                else
                {
                    str = "模板匹配运行失败，请检查你的模板是否正确!";
                }
                throw new Exception(str);
            }
        }
        private bool isDragging = false;  // 标志变量，判断是否正在拖动
        private double mouseStartX;
        private double mouseStartY;
        private HObject dragRegion; //涂抹的区域
        private System.Windows.Forms.Timer drawTimer;  // 定时器，用于定时更新图像
        private void DrawTimer_Tick(object sender, EventArgs e)
        {
            if (HideIntputImage == null) return;
            if (PMA_Contours==null) return;
            if (isDragging)
            {
                // 每次定时器触发时更新拖动区域
                HOperatorSet.GenCircle(out HObject circle, mouseStartY, mouseStartX, double.Parse(pmaForm.smearSize.Value + ""));

                // 如果已有拖动区域，则更新合并
                if (dragRegion != null)
                {
                    HOperatorSet.Union2(dragRegion, circle, out dragRegion);
                }
                else
                {
                    dragRegion = circle;
                }

                // 清除并重新绘制背景图像和拖动区域
                //window.ClearWindow();
                hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(HideIntputImage);  // 重新显示背景图像
                
                hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(dragRegion);  // 显示拖动区域
                HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow,"green"); //模板轮廓的颜色
                hwindowFlowNode.hSmartWindowControl1.HalconWindow.DispObj(PMA_Contours);
                HOperatorSet.SetRgba(hwindowFlowNode.hSmartWindowControl1.HalconWindow, 255, 255, 0, 120);
            }
        }

        private void HSmartWindowControl1_HMouseUp(object sender, HMouseEventArgs e)
        {
            hwindowFlowNode.hSmartWindowControl1.HMoveContent = true;
            pmaForm.hwindowFlowNode.Cursor = Cursors.Default;
            isDragging = false;  // 停止拖动
            drawTimer.Stop();  // 停止定时器
        }

        private void HSmartWindowControl1_HMouseMove(object sender, HMouseEventArgs e)
        {
            mouseStartX = e.X;
            mouseStartY = e.Y;
        }

        // 引用WinAPI函数
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr LoadCursorFromFile(string fileName);

        private void HSmartWindowControl1_HMouseDown(object sender, HMouseEventArgs e)
        {
            if (e.Button==MouseButtons.Left)
            {
                hwindowFlowNode.hSmartWindowControl1.HMoveContent = false;
                isDragging = true;  // 开始拖动
                mouseStartX = e.X;
                mouseStartY = e.Y;
                // 启动定时器，开始定期绘制
                drawTimer.Start();

                Bitmap cursorBitmap = new Bitmap(@"Data\Image\virtual-d.cur"); // 确保是 BMP格式
                Cursor customCursor = CreateCursor(cursorBitmap, 16, 16); // 设置热点为 (16, 16)

                pmaForm.hwindowFlowNode.Cursor = customCursor;
            }
            
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ICONINFO
        {
            public bool fIcon;
            public int xHotspot;
            public int yHotspot;
            public IntPtr hbmMask;
            public IntPtr hbmColor;
        }

        [DllImport("user32.dll")]
        public static extern IntPtr CreateIconIndirect(ref ICONINFO iconInfo);

        [DllImport("user32.dll")]
        public static extern bool DestroyCursor(IntPtr hCursor);

        public static Cursor CreateCursor(Bitmap bmp, int xHotspot, int yHotspot)
        {
            ICONINFO iconInfo = new ICONINFO
            {
                fIcon = false,
                xHotspot = xHotspot,
                yHotspot = yHotspot,
                hbmMask = bmp.GetHbitmap(),
                hbmColor = bmp.GetHbitmap()
            };

            IntPtr cursorPtr = CreateIconIndirect(ref iconInfo);
            return new Cursor(cursorPtr);
        }
        public void Seamer() {
            if (HideIntputImage==null) {
                throw new Exception("输入图像为null,涂抹无法实现");
            }

            HObject ROI_0 = null;
            
            //获取位置信息,谁有值就执行谁
            draw.GetPoint(out HDrawingObjectEx region1);
            drawCirle.GetPoint(out HDrawingObjectEx region2);
            if (region1 != null)
            {
                //矩形
                region = region1;
                HOperatorSet.GenRectangle2(out ROI_0, region.hTuples[0], region.hTuples[1], region.hTuples[2], region.hTuples[3], region.hTuples[4]);
                draw.ClearObject(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            }
            else if (region2 != null)
            {
                //圆形
                region = region2;
                HOperatorSet.GenCircle(out ROI_0, region.hTuples[0], region.hTuples[1], region.hTuples[2]);
                drawCirle.ClearObject(hwindowFlowNode.hSmartWindowControl1.HalconWindow);
            }

            paper = true;
            if (ROI_0 == null) return;
            HOperatorSet.ReduceDomain(HideIntputImage, ROI_0, out HObject imageReduced);

            try
            {
                HOperatorSet.CreateScaledShapeModel(imageReduced, "auto", (new HTuple(-360).TupleRad())
                , (new HTuple(360).TupleRad()), "auto", 0.9, 1.1, "auto", "auto", "use_polarity",
                "auto", "auto", out HideOutputShapeModel);
            }
            catch (HOperatorException e)
            {
                if (e.GetErrorCode() == 3111)
                {
                    DrawRectangle2();
                    CreatShapeModel();
                }
            };
            HOperatorSet.SetColor(hwindowFlowNode.hSmartWindowControl1.HalconWindow, "green");
            HOperatorSet.GetShapeModelContours(out HObject ho_ModelContours, HideOutputShapeModel, 1);
            HOperatorSet.AreaCenter(ROI_0, out HTuple hv_Area, out HTuple hv_Row1, out HTuple hv_Column1);
            //几何变换的实现
            HOperatorSet.HomMat2dIdentity(out HTuple hv_HomMat2DIdentity);
            HOperatorSet.HomMat2dTranslate(hv_HomMat2DIdentity, hv_Row1, hv_Column1, out HTuple hv_HomMat2DTranslate);
            HOperatorSet.HomMat2dRotate(hv_HomMat2DTranslate, 0, hv_Row1, hv_Column1, out HTuple hv_HomMat2DRotate);
            HOperatorSet.HomMat2dScale(hv_HomMat2DRotate, 1, 1, hv_Row1, hv_Column1, out HTuple hv_HomMat2DScale);
            HOperatorSet.AffineTransContourXld(ho_ModelContours, out PMA_Contours, hv_HomMat2DScale);

            HOperatorSet.DispObj(PMA_Contours,hwindowFlowNode.hSmartWindowControl1.HalconWindow);

            pmaForm.toolStripButton2.Enabled = false;
            pmaForm.toolStripButton5.Enabled = false;
            pmaForm.toolStripButton4.Enabled = false;

            hwindowFlowNode.contextMenuStrip1.Items.Add("确认ROI");
            hwindowFlowNode.contextMenuStrip1.Items[hwindowFlowNode.contextMenuStrip1.Items.Count - 1].MouseDown += Shap_S_Matching_MouseDown;

            HOperatorSet.SetRgba(hwindowFlowNode.hSmartWindowControl1.HalconWindow, 255, 255, 0, 120);
            hwindowFlowNode.hSmartWindowControl1.HMouseDown += HSmartWindowControl1_HMouseDown;
            hwindowFlowNode.hSmartWindowControl1.HMouseMove += HSmartWindowControl1_HMouseMove;
            hwindowFlowNode.hSmartWindowControl1.HMouseUp += HSmartWindowControl1_HMouseUp;
            // 初始化定时器
            drawTimer = new System.Windows.Forms.Timer();
            drawTimer.Interval = 1; // 设置定时器每50毫秒触发一次
            drawTimer.Tick += DrawTimer_Tick;  // 定义定时器触发事件
        }

        /// <summary>
        /// 确认ROI涂抹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void Shap_S_Matching_MouseDown(object sender, MouseEventArgs e)
        {
            pmaForm.toolStripButton2.Enabled = true;
            pmaForm.toolStripButton4.Enabled = true;
            pmaForm.toolStripButton5.Enabled = true;
            hwindowFlowNode.hSmartWindowControl1.HMoveContent = true;

            hwindowFlowNode.contextMenuStrip1.Items[1].MouseDown -= Shap_S_Matching_MouseDown;
            hwindowFlowNode.contextMenuStrip1.Items.RemoveAt(hwindowFlowNode.contextMenuStrip1.Items.Count - 1);
            hwindowFlowNode.contextMenuStrip1.Close();

            hwindowFlowNode.hSmartWindowControl1.HMouseDown -= HSmartWindowControl1_HMouseDown;
            hwindowFlowNode.hSmartWindowControl1.HMouseMove -= HSmartWindowControl1_HMouseMove;
            hwindowFlowNode.hSmartWindowControl1.HMouseUp -= HSmartWindowControl1_HMouseUp;
            PMA_Contours = null;
        }
    }
}